#include "Trie.h"

bool erzeuge_kind = false;

Trie::Trie()
{
   root = new Knoten;
   root->setWert('0');
   root->setKind(NULL);
   root->setWeiter(NULL);
}

Trie::~Trie()
{
   destroyTrie(root);
   //printf("Hallo aus dem Trie Destruktor\n");
}

void Trie::destroyTrie(Knoten *uebergabeKnoten) {
   if (uebergabeKnoten != NULL) {
      destroyTrie(uebergabeKnoten->getWeiter());
      destroyTrie(uebergabeKnoten->getKind());
      delete uebergabeKnoten;
   }
}

// Lernen
void Trie::lerneWort(std::string wort)
{
	Knoten *aktuellerKnoten=root;
   
   for (unsigned int i=0; i<wort.length(); i++) {
      if (erzeuge_kind == false) {
         aktuellerKnoten=insert(wort[i], aktuellerKnoten); 
      }
      else {
         aktuellerKnoten=erzeugeKind(wort[i], aktuellerKnoten);
         //std::cout << "Erzeuge Kind: " << wort[i] << std::endl;
      }
   }
   aktuellerKnoten=erzeugeKind('\0', aktuellerKnoten);   
}

Knoten* Trie::insert(char buchst, Knoten *uebergabeKnoten)
{
   Knoten *temporaer;
   if (uebergabeKnoten->getWert() == buchst) {
      //std::cout << "Gehe zum Kind" << std::endl;
      return uebergabeKnoten->getKind();
   }
   else if (uebergabeKnoten->getWert() != buchst && uebergabeKnoten->getWeiter() == NULL) {
      //std::cout << "Setze neu: " << buchst << std::endl;
      uebergabeKnoten->setWeiter(new Knoten(buchst));
      erzeuge_kind = true;
      return uebergabeKnoten->getWeiter();
   }
   else if (uebergabeKnoten->getWert() != buchst && uebergabeKnoten->getWeiter() != NULL) {
      //std::cout << "Gehe weiter wegen: " << buchst << " != " << uebergabeKnoten->getWert() << std::endl;
      temporaer=insert(buchst, uebergabeKnoten->getWeiter());
      return temporaer;
   }
   return NULL;
}

Knoten* Trie::erzeugeKind(char buchst, Knoten *uebergabeKnoten)
{
   uebergabeKnoten->setKind(new Knoten(buchst));
   
   if ( buchst == '\0' )
      erzeuge_kind = false;
   
   return uebergabeKnoten->getKind();
}

// Ende lernen

Knoten* Trie::buchstabeEnthalten(char buchst, Knoten *uebergabeKnoten)
{
   Knoten *temporaer;
   if (uebergabeKnoten->getWert() != buchst && uebergabeKnoten->getWeiter() != NULL) {
      temporaer=buchstabeEnthalten(buchst, uebergabeKnoten->getWeiter());
      return temporaer;
   }
   else if (uebergabeKnoten->getWert() != buchst && uebergabeKnoten->getWeiter() == NULL) {
      return NULL;
   }
   else if (uebergabeKnoten->getWert() == buchst) {
      return uebergabeKnoten->getKind();
   }
   return NULL;
}


bool Trie::kenneIchDasWort(std::string wort)
{
   Knoten *knoten=root;
   for (unsigned int i=0; i<wort.length(); i++) {
      knoten=buchstabeEnthalten(wort[i], knoten);
      if (knoten == NULL) {
         return false;
      }
      else if (knoten->getWert() == '\0') {
         return true;
      }
   }
   return false;
}
